﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace RouteMaster
{
    public class BusRoute
    {
        readonly List<int> _busStopsFromStartToEnd = new List<int>();
        readonly Dictionary<int, Edge> _theStopsVisited = new Dictionary<int, Edge>();
        readonly iWorld _theWorld;
        readonly string _serviceName;
        public readonly int ID;

        public string VehicleType { get; private set; }

        public BusRoute(int id, string serviceName, string vehicleType, iWorld theWorld)
        {
            _theWorld = theWorld;
            _serviceName = serviceName;
            ID = id;
            VehicleType = vehicleType;
        }

        public bool IsStopOnRoute(int id)
        {
            return _theStopsVisited.ContainsKey(id);
        }

        public void AddStop(int busTopID, Edge edge)
        {
            if (_theStopsVisited.Count == 0 && edge != null)
                throw new ApplicationException("Vertex must be null for first node");

            _theStopsVisited.Add(busTopID, edge);
            _busStopsFromStartToEnd.Add(busTopID);
        }

        public TimeSpan GetJourneyTime(int start, int end)
        {
            var ts = new TimeSpan();
            bool foundStart = false;
            foreach (var bsID in _theStopsVisited.Keys)
            {
                if (bsID == start)
                {
                    foundStart = true;
                    continue;
                }
                if (foundStart)
                {
                    ts = ts.Add(_theStopsVisited[bsID]._jouneyTime);
                }

                if (bsID == end)
                    return ts;
            }
            return new TimeSpan();
        }

        public bool IsAGoodRoute(int idFrom, int idTo)
         {
            if (!_theStopsVisited.ContainsKey(idFrom))
                return false;
           
            if (!_theStopsVisited.ContainsKey(idTo))
                return false;

            // both places are on this route but are we going the right way? 

            foreach (int id in _busStopsFromStartToEnd)
            {
                if (id == idTo)
                    return false;

                if (id == idFrom)
                    break; // good we found from first
            }

            return true;
         }
        
        public string RouteName
        {
            get
            {
                return _serviceName;
            }
        }

        public TimeSpan GetJouneyTime()
        {
            var ts = new TimeSpan();
            return _theStopsVisited.Values.Where(e => e != null).Aggregate(ts, (current, e) => current.Add(e._jouneyTime));
        }

        public bool GetOtherStops(int idFrom, List<BusStop> potentialStops)
        {
            if (!_theStopsVisited.ContainsKey(idFrom))
                return false;

            // both places are on this route but are we going the right way? 
           
            bool routeUsed = false;

            bool tick = false;
            foreach (int id in _busStopsFromStartToEnd)
            {
                if (id == idFrom)
                {
                    tick = true;
                    continue;
                }
                if (tick)
                {
                    potentialStops.Add(_theWorld.GetById(id));
                    routeUsed = true;
                }
            }

            return routeUsed;
        }

        public override string ToString()
        {
            return RouteName;
        }
    }
}
